//
// Created by Eric on 2023/1/21.
//

#ifndef UUU_SIMULATIONMANAGER_H
#define UUU_SIMULATIONMANAGER_H
#include <unordered_map>
#include <tuple>
#include <algorithm>
#include "uuu_utility.h"
#include <vector>
#include "EventQueue.h"

using namespace std;

typedef std::unordered_map<int, Civilization> Civilizations;
typedef std::unordered_map<int, AsObject> AsObjects;

class SimulationManager {
public:
    // 这个构造函数负责初始化数据
    SimulationManager(int number_of_civilization, int number_of_asobject, double us);
    void ExecuteEvent(Event &event);


    void RaiseEvent(){
        event_queue_.PushEvent();
    }

    void Execute(){
        for(auto event: event_queue_.GetEventList()){
            ExecuteEvent(event);
        }
    }

    // 模拟入口
    void Simulate(){
        // 获得一个事件
        event_queue_.PushEvent();
//        auto next_event = event_queue_.PopEvent();
        // 执行该事件
    }

public:
    int num_of_civilization_;
    int num_of_asobject_;
    double universe_size_;

    DatabaseInfo dbi_;

public:
    EventQueue event_queue_;
    CivilizationSet civilization_set_;
    AsObjectSet asobject_set_;
    RelationMatrix relation_matrix_;
};

void SimulationManager::ExecuteEvent(Event &event) {
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!注意break！tt
    switch(event.type()){
        case Event::Null:{
            // 那就当然啥也不干
            break;
        }
        case Event::Develop:{
            Civilization& target = civilization_set_.GetCivilization(event.source_cz_idx());

            double new_technology_level = Counter::delta_technology_level(target.technology_level(), target.intelligence());
            target.set_technology_level(new_technology_level);

            break;
        }
        case Event::War:{
            // 这是一次殖民战争
            // 优先判断殖民战争
            if(event.state() & Event::State::Colonize){
                // 直接设置拥有
                relation_matrix_.SetObState(event.source_cz_idx(),  event.target_cz_idx(), RelationMatrix::OWN);
            }

            else{

                // 普通战争
                Civilization& source = civilization_set_.GetCivilization(event.source_cz_idx());

                // 找到发起者和被进攻者
                int source_idx = event.source_cz_idx();
                int target_idx = relation_matrix_.GetAoOwnerId(source_idx);
                Civilization& target = civilization_set_.GetCivilization(target_idx);
                if(target.MilitaryLagBehind(source)){
                    // 发起者不敌
                    relation_matrix_.SetObState(target_idx, event.target_cz_idx(), RelationMatrix::KNOW);
                    relation_matrix_.SetObState(source_idx, event.target_cz_idx(), RelationMatrix::OWN);
                }
                else{
                    // 进攻者不敌
                    break;
                }
            }

            break;
        }
        case Event::Detect:{
            relation_matrix_.SetObState(event.source_cz_idx(), event.target_cz_idx(), RelationMatrix::KNOW);

            auto& civi = civilization_set_.GetCivilization(event.source_cz_idx());
            civi.set_asobject_known(civi.asobject_known()+1);

            break;
        }
        default:
            break;
    }
}

// 初始化这个类的所有变量
SimulationManager::SimulationManager(int number_of_civilization, int number_of_asobject, double us): num_of_asobject_(number_of_asobject), num_of_civilization_(number_of_civilization), universe_size_(us){
    // 初始化所有数据库
    dbi_ = DatabaseInfo (num_of_civilization_, num_of_asobject_, universe_size_, &civilization_set_, &asobject_set_, &relation_matrix_);

    civilization_set_.Initialize(&dbi_);
    asobject_set_.Initialize(&dbi_);
    relation_matrix_.Initialize(&dbi_);
    event_queue_.Initialize(&dbi_);
}
#endif //UUU_SIMULATIONMANAGER_H
